package tests;

import static org.junit.Assert.*;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

import model.Job;
import model.Park;
import model.Role;
import model.User;
import model.WorkLoad;

import org.junit.Before;
import org.junit.Test;

/**
 * Test non-trivial methods of the Job class.
 * 
 * @author Ken Norton
 *
 */
public class JobTest {

  /**
   * Test data  for a Job.
   */
  private static final String JOB1_DATA[] = {"02/22/2012",
    "Clean Up",     "Pick up litter", "Smith Park", 
    "123 Main Method St.", "District 12", "Northwest", 
    "John", "john@park.com"
  };
  
  private Job job1;
  private Job job2;
  private User USERS[];
  
  /**
   * Sets up two 
   */
  @Before
  public void setUp() {
    job1 = new Job();
    DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
    
    try {
      job1.setDate(df.parse(JOB1_DATA[0]));
    } catch (ParseException e) {
      e.printStackTrace();
    }
    
    job1.setTitle(JOB1_DATA[1]);
    job1.setDescription(JOB1_DATA[2]);
    job1.getPark().setName(JOB1_DATA[3]);
    job1.getPark().setAddress(JOB1_DATA[4]);
    job1.getPark().setDistrict(JOB1_DATA[5]);
    job1.getPark().setRegion(JOB1_DATA[6]);
    job1.getPark().setParkManager(new User(JOB1_DATA[7], 
        JOB1_DATA[8], Role.PARK_MANAGER));
    
    job2 = new Job();
    
    try {
      job2.setDate(df.parse(JOB1_DATA[0]));
    } catch (ParseException e) {
      e.printStackTrace();
    }
    
    job2.setTitle(JOB1_DATA[1]);
    job2.setDescription(JOB1_DATA[2]);
    job2.getPark().setName(JOB1_DATA[3]);
    job2.getPark().setAddress(JOB1_DATA[4]);
    job2.getPark().setDistrict(JOB1_DATA[5]);
    job2.getPark().setRegion(JOB1_DATA[6]);
    job2.getPark().setParkManager(new User(JOB1_DATA[7], 
        JOB1_DATA[8], Role.PARK_MANAGER));
    
    USERS = new User[3];
    USERS[0] = new User("steve", "steve@blah.com", 
        Role.VOLUNTEER);
    USERS[1] = new User("bob", "bob@blahoo.com", 
        Role.VOLUNTEER);
    USERS[2] = new User("joe", "joe@shmoe.net", 
        Role.VOLUNTEER);
  }
  
  /**
   * Tests to see if the equals() method will return true 
   * on two objects that are equal.
   */
  @Test
  public void testEqualsTrue() {
    assertTrue("Failed on equals true case.", 
        job1.equals(job2));
  }
  
  /**
   * Tests to see if the equals() method will return false 
   * on two objects that are not equal.
   */
  @Test
  public void testEqualsFalse() {
    job2.setTitle("Clear trails.");
    assertFalse(job1.equals(job2));
  }
  
  /**
   * Tests the constructor.
   */
  @Test
  public void testConstructor() {
    DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
    Date date;
    try {
      date = df.parse(JOB1_DATA[0]);
      User pm = new User(JOB1_DATA[7], JOB1_DATA[8], 
          Role.PARK_MANAGER);
      Park park = new Park(JOB1_DATA[3], JOB1_DATA[4], 
          JOB1_DATA[5], JOB1_DATA[6], pm);
      Job job = new Job(JOB1_DATA[1], JOB1_DATA[2], date, 
          1, park, 0, 0, "", 0, 0, "", 0, 0, "");
      assertTrue("Failed to correctly construct Job.", 
          job.equals(job1));
    } catch (final ParseException the_exception) {
      the_exception.printStackTrace();
    }
  }
  
  /**
   * Tests the addVolunteer() method of the Job class.
   */
  @Test
  public void testAddGetVolunteer() {
    HashMap<User, WorkLoad> test_map = 
        new HashMap<User, WorkLoad>();
    
    int filled = job1.getMediumWorkFilled();
    
    for (int i = 0; i < 3; i++) {
      job1.addVolunteer(USERS[i], WorkLoad.MEDIUM);
      test_map.put(USERS[i], WorkLoad.MEDIUM);
      filled++;
    }
    
    HashMap<User, WorkLoad> map = 
        (HashMap<User, WorkLoad>) job1.getVolunteers();
    
    assertEquals("Failed to add volunteer.", map, 
        test_map);
    
    assertEquals("Failed to increment the WorkLoad filled.",
        filled, job1.getMediumWorkFilled());
  } 
  
  /**
   * Tests that the getVolunteers() method of the Job class.
   */
  @Test
  public void testRemoveVolunteer() {
    for (int i = 0; i < 3; i++) {
      job1.addVolunteer(USERS[i], WorkLoad.MEDIUM);
    }
    int filled = job1.getMediumWorkFilled();
    HashMap<User, WorkLoad> map = 
        (HashMap<User, WorkLoad>) job1.getVolunteers();
    job1.removeVolunteer(USERS[0]);
    
    assertFalse("Failed to remove volunteer.", 
        map.containsKey(USERS[0]));
    
    assertEquals("Failed to decrement field for " +
    		"WorkLoadFilled.", filled - 1, 
    		job1.getMediumWorkFilled());
  }
}
